﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Csharp.Equality {
    public class PointClass : IEquatable<PointClass> {

        public PointClass(Int32 x, Int32 y) {
            X = x;
            Y = y;
        }

        public Int32 X { get; set; }

        public Int32 Y { get; set; }

        public bool Equals(PointClass other) {
            if (other == null)
                return false;
            if (Object.ReferenceEquals(other, this))
                return true;

            /* Should base this comparison on the hash code
             * of each object. That way, if fields are added
             * or changed, you only have to update how the
             * hash code is calculated. All equality methods
             * are automatically updated. */
            return (GetHashCode() == other.GetHashCode());
        }

        // Sealed to prevent subclasses from breaking equality.
        public sealed override bool Equals(object obj) {
            var objAsPoint = obj as PointClass;
            if (objAsPoint != null)
                return Equals(objAsPoint);
            else
                return false;
        }

        public override int GetHashCode() {
            /* The easiest way derive a hash code is to
             * simply use an exclusive or on the hash 
             * codes of all the fields used for equality.*/
            return X.GetHashCode() ^ Y.GetHashCode();
        }

        public static bool operator ==(PointClass point1, PointClass point2) {
            /* For classes, nulls need to be checked for. Fortunately,
             * the Object.Equals(object, object) method handles that
             * for you. Then is calls Object.Equals(Object), which
             * has already been overridden.*/
            return Object.Equals(point1, point2);
        }

        public static bool operator !=(PointClass point1, PointClass point2) {
            return !(point1 == point2);
        }
    }
}
